#ifndef VISIONLOCATIONCONFIG_H
#define VISIONLOCATIONCONFIG_H

#include "configManager/configobject.h"
#include "scvision.h"
#include "scvision_global.h"
#include <QFileInfo>

class SCVISIONSHARED_EXPORT VisionLocationConfig : public ConfigObject
{
    Q_OBJECT

    Q_PROPERTY(QString locationName READ locationName WRITE setLocationName NOTIFY locationNameChanged)
    Q_PROPERTY(QString calibrationName READ calibrationName WRITE setCalibrationName NOTIFY calibrationNameChanged)
    Q_PROPERTY(QString prFileName READ prFileName WRITE setPrFileName NOTIFY prFileNameChanged)
    Q_PROPERTY(QString cameraName READ cameraName WRITE setCameraName NOTIFY cameraNameChanged)
    Q_PROPERTY(QString prType READ prType WRITE setPrType NOTIFY prTypeChanged)
    Q_PROPERTY(int lightBrightness READ lightBrightness WRITE setLightBrightness NOTIFY lightBrightnessChanged)
    Q_PROPERTY(int secondLightBrightness READ secondLightBrightness WRITE setSecondLightBrightness NOTIFY
                   secondLightBrightnessChanged)
    Q_PROPERTY(double minXOffset READ minXOffset WRITE setMinXOffset NOTIFY minXOffsetChanged)
    Q_PROPERTY(double maxXOffset READ maxXOffset WRITE setMaxXOffset NOTIFY maxXOffsetChanged)
    Q_PROPERTY(double minYOffset READ minYOffset WRITE setMinYOffset NOTIFY minYOffsetChanged)
    Q_PROPERTY(double maxYOffset READ maxYOffset WRITE setMaxYOffset NOTIFY maxYOffsetChanged)
    Q_PROPERTY(double maximunAngle READ maximunAngle WRITE setMaximunAngle NOTIFY maximunAngleChanged)
    Q_PROPERTY(double waitImageDelay READ waitImageDelay WRITE setWaitImageDelay NOTIFY waitImageDelayChanged)
    Q_PROPERTY(double objectScore READ objectScore WRITE setObjectScore NOTIFY objectScoreChanged)
    Q_PROPERTY(
        bool saveImageAfterGrab READ saveImageAfterGrab WRITE setSaveImageAfterGrab NOTIFY saveImageAfterGrabChanged)
    Q_PROPERTY(bool saveResultImage READ saveResultImage WRITE setSaveResultImage NOTIFY saveResultImageChanged)
    Q_PROPERTY(int continuoullyPrROICount READ continuoullyPrROICount WRITE setContinuoullyPrROICount NOTIFY continuoullyPrROICountChanged)
    Q_PROPERTY(int continuoullyPrDelay READ continuoullyPrDelay WRITE setContinuoullyPrDelay NOTIFY continuoullyPrDelayChanged)

public:
    Q_INVOKABLE VisionLocationConfig(QObject *parent = nullptr) : ConfigObject(parent)
    {
        setReadOnlyProperty("locationName");
        setReadOnlyProperty("calibrationName");
        setSelectFileProperty("prFileName", false);
        setOptionalProperty("prType", toVariantList(SCVision::PrTypeEnumInfo().names()));
        init();
    }

    void setOptionalCamera(QStringList cameraNames)
    {
        setOptionalProperty("cameraName", toVariantList(cameraNames));
    }

    QString prFileName() const
    {
        return m_prFileName;
    }

    QString cameraName() const
    {
        return m_cameraName;
    }

    int lightBrightness() const
    {
        return m_lightBrightness;
    }

    double maximunAngle() const
    {
        return m_maximunAngle;
    }

    QString locationName() const
    {
        return m_locationName;
    }

    QString calibrationName() const
    {
        return m_calibrationName;
    }

    double waitImageDelay() const
    {
        return m_waitImageDelay;
    }

    double objectScore() const
    {
        return m_objectScore;
    }

    QString prType() const
    {
        return m_prType;
    }

    Q_INVOKABLE QString prResultImage() const
    {
        return m_prResultImage;
    }

    bool saveImageAfterGrab() const
    {
        return m_saveImageAfterGrab;
    }

    int secondLightBrightness() const
    {
        return m_secondLightBrightness;
    }

    double minXOffset() const
    {
        return m_minXOffset;
    }

    double maxXOffset() const
    {
        return m_maxXOffset;
    }

    double minYOffset() const
    {
        return m_minYOffset;
    }

    double maxYOffset() const
    {
        return m_maxYOffset;
    }

    bool saveResultImage() const
    {
        return m_saveResultImage;
    }

    int continuoullyPrROICount() const
    {
        return m_continuoullyPrROICount;
    }

    int continuoullyPrDelay() const
    {
        return m_continuoullyPrDelay;
    }

public slots:
    void setPrFileName(QString prFileName)
    {
        if (m_prFileName == prFileName)
            return;

        m_prFileName = prFileName;
        if (prFileName.endsWith(".avdata"))
        {
            QString resultImageName = m_prFileName;
            resultImageName.replace(".avdata", "_resultImage.jpg");
            if (QFile::exists(resultImageName))
            {
                m_prResultImage = QString("file:///") + QFileInfo(resultImageName).absoluteFilePath();
            }
            else
            {
                m_prResultImage = "";
            }
        }
        emit prFileNameChanged(m_prFileName);
    }

    void setCameraName(QString cameraName)
    {
        if (m_cameraName == cameraName)
            return;

        m_cameraName = cameraName;
        emit cameraNameChanged(m_cameraName);
    }

    void setLightBrightness(int lightBrightness)
    {
        if (m_lightBrightness == lightBrightness)
            return;

        m_lightBrightness = lightBrightness;
        emit lightBrightnessChanged(m_lightBrightness);
    }

    void setMaximunAngle(double maximunAngle)
    {
        if (qFuzzyCompare(m_maximunAngle, maximunAngle))
            return;

        m_maximunAngle = maximunAngle;
        emit maximunAngleChanged(m_maximunAngle);
    }

    void setLocationName(QString lcationName)
    {
        if (m_locationName == lcationName)
            return;

        m_locationName = lcationName;
        emit locationNameChanged(m_locationName);
    }

    void setCalibrationName(QString calibrationName)
    {
        if (m_calibrationName == calibrationName)
            return;

        m_calibrationName = calibrationName;
        emit calibrationNameChanged(m_calibrationName);
    }

    void setWaitImageDelay(double waitImageDelay)
    {
        if (qFuzzyCompare(m_waitImageDelay, waitImageDelay))
            return;

        m_waitImageDelay = waitImageDelay;
        emit waitImageDelayChanged(m_waitImageDelay);
    }

    void setObjectScore(double objectScore)
    {
        if (qFuzzyCompare(m_objectScore, objectScore))
            return;

        m_objectScore = objectScore;
        emit objectScoreChanged(m_objectScore);
    }

    void setPrType(QString prType)
    {
        if (m_prType == prType)
            return;

        m_prType = prType;
        emit prTypeChanged(m_prType);
    }

    void setSaveImageAfterGrab(bool saveImageAfterGrab)
    {
        if (m_saveImageAfterGrab == saveImageAfterGrab)
            return;

        m_saveImageAfterGrab = saveImageAfterGrab;
        emit saveImageAfterGrabChanged(m_saveImageAfterGrab);
    }

    void setSecondLightBrightness(int secondLightBrightness)
    {
        if (m_secondLightBrightness == secondLightBrightness)
            return;

        m_secondLightBrightness = secondLightBrightness;
        emit secondLightBrightnessChanged(m_secondLightBrightness);
    }

    void setMinXOffset(double minXOffset)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_minXOffset, minXOffset))
            return;

        m_minXOffset = minXOffset;
        emit minXOffsetChanged(m_minXOffset);
    }

    void setMaxXOffset(double maxXOffset)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_maxXOffset, maxXOffset))
            return;

        m_maxXOffset = maxXOffset;
        emit maxXOffsetChanged(m_maxXOffset);
    }

    void setMinYOffset(double minYOffset)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_minYOffset, minYOffset))
            return;

        m_minYOffset = minYOffset;
        emit minYOffsetChanged(m_minYOffset);
    }

    void setMaxYOffset(double maxYOffset)
    {
        //        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_maxYOffset, maxYOffset))
            return;

        m_maxYOffset = maxYOffset;
        emit maxYOffsetChanged(m_maxYOffset);
    }

    void setSaveResultImage(bool saveResultImage)
    {
        if (m_saveResultImage == saveResultImage)
            return;

        m_saveResultImage = saveResultImage;
        emit saveResultImageChanged(m_saveResultImage);
    }

    void setContinuoullyPrROICount(int continuoullyPrROICount)
    {
        if (m_continuoullyPrROICount == continuoullyPrROICount)
            return;

        m_continuoullyPrROICount = continuoullyPrROICount;
        emit continuoullyPrROICountChanged(m_continuoullyPrROICount);
    }

    void setContinuoullyPrDelay(int continuoullyPrDelay)
    {
        if (m_continuoullyPrDelay == continuoullyPrDelay)
            return;

        m_continuoullyPrDelay = continuoullyPrDelay;
        emit continuoullyPrDelayChanged(m_continuoullyPrDelay);
    }

signals:
    void prFileNameChanged(QString prFileName);

    void cameraNameChanged(QString cameraName);

    void lightBrightnessChanged(int lightBrightness);

    void maximunAngleChanged(double maximunAngle);

    void locationNameChanged(QString locationName);

    void calibrationNameChanged(QString calibrationName);

    void waitImageDelayChanged(double waitImageDelay);

    void objectScoreChanged(double objectScore);

    void prTypeChanged(QString prType);

    void saveImageAfterGrabChanged(bool saveImageAfterGrab);

    void secondLightBrightnessChanged(int secondLightBrightness);

    void minXOffsetChanged(double minXOffset);

    void maxXOffsetChanged(double maxXOffset);

    void minYOffsetChanged(double minYOffset);

    void maxYOffsetChanged(double maxYOffset);

    void saveResultImageChanged(bool saveResultImage);

    void continuoullyPrROICountChanged(int continuoullyPrROICount);

    void continuoullyPrDelayChanged(int continuoullyPrDelay);

private:
    QString m_prFileName = "";
    QString m_cameraName = "";
    int m_lightBrightness = 0;
    double m_maximunAngle = 44;
    QString m_locationName = "";
    QString m_calibrationName = "";
    double m_waitImageDelay = 0;
    double m_objectScore = 0.7;
    QString m_prType = SCVision::PrTypeEnumInfo().enumToName(SCVision::Generic_NCC_Template_Matching);
    QString m_prResultImage;
    bool m_saveImageAfterGrab = false;
    int m_secondLightBrightness = 0;
    double m_minXOffset = -5;
    double m_maxXOffset = 5;
    double m_minYOffset = -5;
    double m_maxYOffset = 5;
    bool m_saveResultImage = false;
    int m_continuoullyPrROICount = 1;
    int m_continuoullyPrDelay = -1;
};

#endif    // VISIONLOCATIONCONFIG_H
